﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Company.StudyClub.Model;
using Company.StudyClub.DAL;

namespace Company.StudyClub.BLL.Site
{
    public class ConfigLayer
    {
        private static ConfigLayer instance = null;
        private ConfigLayer()
        {
            this.Init();
        }
        private static readonly object padlock = new object();
        public static ConfigLayer Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (padlock)
                    {
                        instance = new ConfigLayer();
                    }
                }
                return instance;
            }
        }

        private void Init()
        {
            ArrayList variableEntityCollection = new ArrayList();
            // Push to Cache
            Cache.CacheManager.Insert(variableEntityCollection, Cache.CacheManager.CONFIG_KEY, TimeSpan.FromMinutes(Cache.CacheManager.CONFIG_REFRESH_LENGTH));
            this.lastRefreshedDate = DateTime.Now;
        }

        public int GetInt(string keyName, Site_Enviroment environment)
        {
            string keyValue = this.GetValue(keyName, environment);
            if (keyValue == null)
                return -1;
            try
            {
                return Int32.Parse(keyValue.Trim());
            }
            catch
            {
                return 0;
            }
        }
        public bool GetBool(string keyName, Site_Enviroment environment)
        {
            string keyValue = this.GetValue(keyName, environment);
            if (keyValue == null)
                return false;
            try
            {
                return Boolean.Parse(keyValue.Trim().ToLower());
            }
            catch
            {
                return false;
            }
        }
        public string GetString(string keyName, Site_Enviroment environment)
        {
            return this.GetValue(keyName, environment);
        }

        private string GetValue(string keyName, Site_Enviroment environment)
        {
            Site_ConfigVariable variable = new Site_ConfigVariable();
            variable.VariableID = 0;
            // Find Variable in Cache
            ArrayList variableCollection = this.VariableEntityCollection;
            if (variableCollection != null)
            {
                for (int i = 0; i < variableCollection.Count; i++)
                {
                    Site_ConfigVariable tmpVariable = (Site_ConfigVariable)variableCollection[i];
                    if (tmpVariable.KeyName.Trim().ToLower() == keyName.Trim().ToLower())
                    {
                        variable = tmpVariable;
                        break;
                    }
                }
            }
            if (variable.VariableID == 0)
            {
                // Can not be found in Cache, go to search in database, and then push into the cache.
                Site_ConfigVariable objVariable = DAL.Site.ConfigDAL.GetModelByName(keyName.Trim());
               
                if (objVariable != null)
                {
                    variable.VariableID = objVariable.VariableID;
                    variable.KeyName = objVariable.VariableName;
                    variable.DefaultValue = objVariable.DefaultValue;
                    ArrayList valueCollection = new ArrayList();
                    // Value Collection
                    variable.ValuesEntityCollection = DAL.Site.ConfigDAL.SearchConfigValues(objVariable.VariableID);

                    // Update Cache
                    this.UpdateCache(variable);                   
                }
            }

            if (variable.VariableID == 0)
            {
                // Can not find in database either, return null
                return null;
            }

            // If there is no value collection, return default value
            if (variable.ValuesEntityCollection.Count == 0)
                return variable.DefaultValue;

            // Get value from value collection
            for (int j = 0; j < variable.ValuesEntityCollection.Count; j++)
            {
                Site_ConfigValue objValue = (Site_ConfigValue)variable.ValuesEntityCollection[j];
                if ((objValue.Area.Length == 0 || objValue.Area.ToLower() == environment.Area.ToLower())
                    && (objValue.BeginDate == DateTime.Parse("1900-1-1") || objValue.BeginDate <= DateTime.Now)
                    && (objValue.EndDate == DateTime.Parse("1900-1-1") || objValue.EndDate >= DateTime.Now)
                    && (objValue.ServerName.Length == 0 || objValue.ServerName.ToLower() == environment.ServerName.ToLower())
                    && (objValue.MemberType.Length == 0 || objValue.MemberType.ToLower() == environment.MemberType.ToLower())
                    && (objValue.Language.Length == 0 || objValue.Language.ToLower() == environment.Language.ToLower()))
                {
                    return objValue.KeyValue;
                }
            }

            // Can not find in value collection
            return variable.DefaultValue;
        }

        public void Refresh()
        {
            try
            {
                this.Init();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private ArrayList VariableEntityCollection
        {
            get
            {
                object list = Cache.CacheManager.Get(Cache.CacheManager.CONFIG_KEY);
                if (list == null)
                    this.Init();
                return (ArrayList)Cache.CacheManager.Get(Cache.CacheManager.CONFIG_KEY);
            }
        }

        private void UpdateCache(Site_ConfigVariable variableEntity)
        {
            this.VariableEntityCollection.Add(variableEntity);
            Cache.CacheManager.Insert(this.VariableEntityCollection, Cache.CacheManager.CONFIG_KEY, TimeSpan.FromMinutes(Cache.CacheManager.CONFIG_REFRESH_LENGTH));
        }

        private DateTime lastRefreshedDate;
        public DateTime LastRefreshedDate
        {
            get { return this.lastRefreshedDate; }
            set { this.lastRefreshedDate = value; }
        }
    }
}
